Skip to content

fix(goal): tolerate vanished-session message windows, surface loop failures - #283

Merged
LeXwDeX merged 2 commits into
devfrom
fix/goal-visibility
Aug 15, 2026
Merged

fix(goal): tolerate vanished-session message windows, surface loop failures#283
LeXwDeX merged 2 commits into
devfrom
fix/goal-visibility

Conversation

@LeXwDeX

@LeXwDeX LeXwDeX commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Problem

Goal 状态机静默卡死:afterIdle 在 lease claim 后读取消息窗口(sessions.messages({limit:20})),当 session 行不存在中被删除或合成会话)时,MessageV2.pageNotFoundError。该 typed failure 逃逸后被 triggerEvaluation fork 处的 Effect.ignore 静默吞噬——goal 永久 active、零日志、turns_used 恒 0。生产事故 + 复现探针(bootstrap-wiring.test.ts,走 AppRuntime→InstanceStore→bootstrap.run 生产装配)证实断点;僵尸守卫的 messages({limit:1}) 有同样隐患。

Fix

  1. afterIdle + 僵尸探针:消息窗口的 NotFoundError 视为空窗口(与 MessageV2.stream 同模式)→ 走已有的「无 assistant → 可见 pause」分支
  2. fork 点可观测Effect.ignore 换成 catchCause + logWarning(interrupt 保持静默,F1 纪律),任何 afterIdle 失败可诊断
  3. 回归测试:生产装配探针(修复前 RED、修复后 GREEN)+ NotFoundError 窗口暂停聚焦用例

Evidence

  • 断点定位:子代理逐阶段探针(bootstrap serviceOption=Some→订阅武装→ownsSession=true→claim Some→messages NotFoundError 逃逸)
  • bun typecheck 干净;test/goal 101 pass / 0 fail(90 既有 + 探针 + 新用例)
  • grilling 共识:a+b 修复、保留探针、遗留卡死 row 靠修复后代码自证、本次只做止血(Hermes 语义对齐另行任务)

release: dev → main (goal turn-scope, hook headers, tui question tabs)
…ilures

Root cause of the invisible goal stall: the afterIdle evaluation died on a
typed NotFoundError from the messages-window read (session row gone mid-goal,
or a synthetic session), and the fork's bare Effect.ignore swallowed it —
goal left permanently active, turns_used frozen at 0, zero logs.

- afterIdle + zombie probe + post-judge reload: NotFoundError on any of the
  three messages windows degrades to an empty window (MessageV2.stream
  pattern) so the existing visible branches handle it (pause / continuation)
- triggerEvaluation fork: Effect.ignore -> catchCause + logWarning (interrupts
  stay silent per F1) so future evaluation failures are diagnosable
- judge chain: orElseSucceed -> catchCause so DEFECTS in the production
  provider chain (config orDie, payload decode) fold into the parseFailed
  budget instead of silently killing the evaluation
- auto-pause transcript line: ignore -> catchCause + logWarning (symmetric
  with the done branch)
- P2-B comment corrected: effect v4 Effect.ignore absorbs defects too;
  catchCause's value here is diagnosability, not subscription survival
- regression tests: production-wiring probe (bootstrap-wiring.test.ts),
  pre-judge window pause, post-judge reload tolerance (GOAL-FP-01-18),
  judge-defect budget degradation (GOAL-FP-01-18b)
- lint: new code is warning-neutral; drop 11 pre-existing unused imports to
  restore gate margin (oxlint ratchet, local 4846 -> 4829)
@LeXwDeX
LeXwDeX force-pushed the fix/goal-visibility branch from bd64abc to 53a2ad3 Compare August 15, 2026 18:51
@LeXwDeX
LeXwDeX merged commit cfb1914 into dev Aug 15, 2026
5 checks passed
@LeXwDeX
LeXwDeX deleted the fix/goal-visibility branch August 15, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant